﻿Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Workflow.ComponentModel

Namespace System.Workflow.ComponentModel.Design
    Friend Class PropertyDescriptorFilter
        ' Methods
        Friend Shared Sub FilterProperties(ByVal serviceProvider As IServiceProvider, ByVal propertyOwner As Object, ByVal props As IDictionary)
            PropertyDescriptorFilter.InternalFilterProperties(serviceProvider, propertyOwner, props)
            If (Not propertyOwner Is Nothing) Then
                Dim descriptor As PropertyDescriptor
                For Each descriptor In PropertyDescriptorFilter.GetPropertiesForEvents(serviceProvider, propertyOwner)
                    If Not props.Contains(descriptor.Name) Then
                        props.Add(descriptor.Name, descriptor)
                    End If
                Next
            End If
        End Sub

        Friend Shared Function FilterProperties(ByVal serviceProvider As IServiceProvider, ByVal propertyOwner As Object, ByVal props As PropertyDescriptorCollection) As PropertyDescriptorCollection
            Dim hashtable As New Hashtable
            Dim descriptor As PropertyDescriptor
            For Each descriptor In props
                If Not hashtable.ContainsKey(descriptor.Name) Then
                    hashtable.Add(descriptor.Name, descriptor)
                End If
            Next
            PropertyDescriptorFilter.FilterProperties(serviceProvider, propertyOwner, hashtable)
            Dim array As PropertyDescriptor() = New PropertyDescriptor(hashtable.Count  - 1) {}
            hashtable.Values.CopyTo(array, 0)
            Return New PropertyDescriptorCollection(array)
        End Function

        Friend Shared Function GetPropertiesForEvents(ByVal serviceProvider As IServiceProvider, ByVal eventOwner As Object) As PropertyDescriptorCollection
            Dim list As New List([Of] PropertyDescriptor)
            Dim service As IEventBindingService = [TryCast](serviceProvider.GetService(GetType(IEventBindingService)),IEventBindingService)
            If (Not service Is Nothing) Then
                Dim descriptor As EventDescriptor
                For Each descriptor In TypeDescriptor.GetEvents(eventOwner)
                    If descriptor.IsBrowsable Then
                        Dim eventProperty As PropertyDescriptor = service.GetEventProperty(descriptor)
                        If (Not TypeOf eventProperty Is ActivityBindPropertyDescriptor AndAlso ActivityBindPropertyDescriptor.IsBindableProperty(eventProperty)) Then
                            list.Add(New ActivityBindPropertyDescriptor(serviceProvider, eventProperty, eventOwner))
                        Else
                            list.Add(eventProperty)
                        End If
                    End If
                Next
            End If
            Return New PropertyDescriptorCollection(list.ToArray)
        End Function

        Private Shared Sub InternalFilterProperties(ByVal serviceProvider As IServiceProvider, ByVal propertyOwner As Object, ByVal properties As IDictionary)
            Dim hashtable As New Hashtable
            Dim obj2 As Object
            For Each obj2 In properties.Keys
                Dim actualPropDesc As PropertyDescriptor = [TryCast](properties.Item(obj2),PropertyDescriptor)
                If (String.Equals(actualPropDesc.Name, "Name", StringComparison.Ordinal) AndAlso GetType(Activity).IsAssignableFrom(actualPropDesc.ComponentType)) Then
                    Dim activity As Activity = [TryCast](propertyOwner,Activity)
                    If ((Not activity Is Nothing) AndAlso (activity Is Helpers.GetRootActivity(activity))) Then
                        hashtable.Item(obj2) = New NamePropertyDescriptor(serviceProvider, actualPropDesc)
                    Else
                        hashtable.Item(obj2) = New IDPropertyDescriptor(serviceProvider, actualPropDesc)
                    End If
                    [Continue] For
                End If
                If (Not TypeOf actualPropDesc Is ActivityBindPropertyDescriptor AndAlso ActivityBindPropertyDescriptor.IsBindableProperty(actualPropDesc)) Then
                    If (GetType(Type).IsAssignableFrom(actualPropDesc.PropertyType) AndAlso Not TypeOf actualPropDesc Is ParameterInfoBasedPropertyDescriptor) Then
                        actualPropDesc = New TypePropertyDescriptor(serviceProvider, actualPropDesc)
                    End If
                    hashtable.Item(obj2) = New ActivityBindPropertyDescriptor(serviceProvider, actualPropDesc, propertyOwner)
                    [Continue] For
                End If
                If GetType(Type).IsAssignableFrom(actualPropDesc.PropertyType) Then
                    hashtable.Item(obj2) = New TypePropertyDescriptor(serviceProvider, actualPropDesc)
                Else
                    hashtable.Item(obj2) = New DynamicPropertyDescriptor(serviceProvider, actualPropDesc)
                End If
            Next
            Dim obj3 As Object
            For Each obj3 In hashtable.Keys
                properties.Item(obj3) = hashtable.Item(obj3)
            Next
        End Sub

    End Class
End Namespace

